using System;
using System.Collections.Generic;
using UnityEngine;

namespace GameSystems
{
    /// <summary>
    /// 用户数据管理器 - 处理用户信息的存储和读取
    /// </summary>
    [CreateAssetMenu(fileName = "UserDataManager", menuName = "Game Systems/User Data Manager")]
    public class UserDataManager : ScriptableObject
    {
        #region Data Classes

        /// <summary>
        /// 用户数据结构
        /// </summary>
        [Serializable]
        public class UserData
        {
            public string username;
            public string email;
            public DateTime lastLoginDate;
            public int totalPlayTime;
            public int loginCount;
            public Dictionary<string, object> customData;

            public UserData()
            {
                customData = new Dictionary<string, object>();
                lastLoginDate = DateTime.Now;
                totalPlayTime = 0;
                loginCount = 0;
            }
        }

        #endregion

        #region Serialized Fields

        [Header("数据存储配置")]
        [Tooltip("数据文件名")]
        [SerializeField] private string dataFileName = "UserData.json";

        [Tooltip("是否启用加密")]
        [SerializeField] private bool enableEncryption = false;

        [Tooltip("加密密钥（仅在启用加密时使用）")]
        [SerializeField] private string encryptionKey = "DefaultKey123";

        [Header("自动保存配置")]
        [Tooltip("自动保存间隔（秒）")]
        [SerializeField] private float autoSaveInterval = 60f;

        [Tooltip("是否启用自动保存")]
        [SerializeField] private bool enableAutoSave = true;

        #endregion

        #region Private Fields

        private UserData currentUserData;
        private float lastSaveTime;
        private bool isDirty = false;

        // 临时存储所有用户数据（实际项目中应该使用数据库）
        private Dictionary<string, UserData> allUsersData = new Dictionary<string, UserData>();

        #endregion

        #region Public Properties

        /// <summary>
        /// 当前用户数据
        /// </summary>
        public UserData CurrentUserData => currentUserData;

        /// <summary>
        /// 是否有未保存的更改
        /// </summary>
        public bool IsDirty => isDirty;

        #endregion

        #region Public Methods

        /// <summary>
        /// 初始化用户数据
        /// </summary>
        /// <param name="username">用户名</param>
        public void InitializeUser(string username)
        {
            if (string.IsNullOrEmpty(username))
            {
                Debug.LogError("用户名不能为空");
                return;
            }

            LoadUserData(username);

            if (currentUserData == null)
            {
                CreateNewUser(username);
            }

            UpdateLoginData();
        }

        /// <summary>
        /// 保存用户数据
        /// </summary>
        public void SaveUserData()
        {
            if (currentUserData == null)
            {
                Debug.LogWarning("没有可保存的用户数据");
                return;
            }

            try
            {
                string jsonData = JsonUtility.ToJson(currentUserData, true);

                if (enableEncryption)
                {
                    jsonData = EncryptData(jsonData);
                }

                string filePath = GetUserDataFilePath(currentUserData.username);
                System.IO.File.WriteAllText(filePath, jsonData);

                allUsersData[currentUserData.username] = currentUserData;

                isDirty = false;
                lastSaveTime = Time.time;

                Debug.Log($"用户数据已保存: {currentUserData.username}");
            }
            catch (Exception e)
            {
                Debug.LogError($"保存用户数据失败: {e.Message}");
            }
        }

        /// <summary>
        /// 加载用户数据
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>是否加载成功</returns>
        public bool LoadUserData(string username)
        {
            if (string.IsNullOrEmpty(username))
            {
                Debug.LogError("用户名不能为空");
                return false;
            }

            try
            {
                string filePath = GetUserDataFilePath(username);

                if (!System.IO.File.Exists(filePath))
                {
                    Debug.Log($"用户数据文件不存在: {username}");
                    return false;
                }

                string jsonData = System.IO.File.ReadAllText(filePath);

                if (enableEncryption)
                {
                    jsonData = DecryptData(jsonData);
                }

                currentUserData = JsonUtility.FromJson<UserData>(jsonData);

                if (currentUserData != null)
                {
                    allUsersData[username] = currentUserData;
                    Debug.Log($"用户数据已加载: {username}");
                    return true;
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"加载用户数据失败: {e.Message}");
            }

            return false;
        }

        /// <summary>
        /// 删除用户数据
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>是否删除成功</returns>
        public bool DeleteUserData(string username)
        {
            if (string.IsNullOrEmpty(username))
            {
                Debug.LogError("用户名不能为空");
                return false;
            }

            try
            {
                string filePath = GetUserDataFilePath(username);

                if (System.IO.File.Exists(filePath))
                {
                    System.IO.File.Delete(filePath);
                }

                allUsersData.Remove(username);

                if (currentUserData != null && currentUserData.username == username)
                {
                    currentUserData = null;
                }

                Debug.Log($"用户数据已删除: {username}");
                return true;
            }
            catch (Exception e)
            {
                Debug.LogError($"删除用户数据失败: {e.Message}");
                return false;
            }
        }

        /// <summary>
        /// 更新用户自定义数据
        /// </summary>
        /// <param name="key">数据键</param>
        /// <param name="value">数据值</param>
        public void UpdateCustomData(string key, object value)
        {
            if (currentUserData == null)
            {
                Debug.LogWarning("当前没有登录用户");
                return;
            }

            currentUserData.customData[key] = value;
            isDirty = true;

            if (enableAutoSave)
            {
                CheckAutoSave();
            }
        }

        /// <summary>
        /// 获取用户自定义数据
        /// </summary>
        /// <param name="key">数据键</param>
        /// <returns>数据值</returns>
        public object GetCustomData(string key)
        {
            if (currentUserData == null || !currentUserData.customData.ContainsKey(key))
            {
                return null;
            }

            return currentUserData.customData[key];
        }

        /// <summary>
        /// 增加游戏时间
        /// </summary>
        /// <param name="seconds">增加的秒数</param>
        public void AddPlayTime(int seconds)
        {
            if (currentUserData == null)
            {
                Debug.LogWarning("当前没有登录用户");
                return;
            }

            currentUserData.totalPlayTime += seconds;
            isDirty = true;

            if (enableAutoSave)
            {
                CheckAutoSave();
            }
        }

        /// <summary>
        /// 获取所有用户列表
        /// </summary>
        /// <returns>用户名列表</returns>
        public List<string> GetAllUsernames()
        {
            List<string> usernames = new List<string>();

            try
            {
                string dataPath = GetUserDataDirectory();

                if (System.IO.Directory.Exists(dataPath))
                {
                    string[] files = System.IO.Directory.GetFiles(dataPath, "*.json");

                    foreach (string file in files)
                    {
                        string filename = System.IO.Path.GetFileNameWithoutExtension(file);
                        usernames.Add(filename);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"获取用户列表失败: {e.Message}");
            }

            return usernames;
        }

        /// <summary>
        /// 清除当前用户数据
        /// </summary>
        public void ClearCurrentUser()
        {
            if (isDirty && currentUserData != null)
            {
                SaveUserData();
            }

            currentUserData = null;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 创建新用户
        /// </summary>
        /// <param name="username">用户名</param>
        private void CreateNewUser(string username)
        {
            currentUserData = new UserData
            {
                username = username,
                email = "",
                lastLoginDate = DateTime.Now,
                totalPlayTime = 0,
                loginCount = 0
            };

            isDirty = true;
            Debug.Log($"创建新用户: {username}");
        }

        /// <summary>
        /// 更新登录数据
        /// </summary>
        private void UpdateLoginData()
        {
            if (currentUserData == null) return;

            currentUserData.lastLoginDate = DateTime.Now;
            currentUserData.loginCount++;
            isDirty = true;
        }

        /// <summary>
        /// 检查是否需要自动保存
        /// </summary>
        private void CheckAutoSave()
        {
            if (!enableAutoSave) return;

            if (Time.time - lastSaveTime >= autoSaveInterval)
            {
                SaveUserData();
            }
        }

        /// <summary>
        /// 获取用户数据文件路径
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>文件路径</returns>
        private string GetUserDataFilePath(string username)
        {
            return System.IO.Path.Combine(GetUserDataDirectory(), $"{username}.json");
        }

        /// <summary>
        /// 获取用户数据目录
        /// </summary>
        /// <returns>目录路径</returns>
        private string GetUserDataDirectory()
        {
            string path = System.IO.Path.Combine(Application.persistentDataPath, "UserData");

            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            return path;
        }

        /// <summary>
        /// 加密数据
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <returns>加密后的数据</returns>
        private string EncryptData(string data)
        {
            // 这里是简单的XOR加密示例
            // 实际项目中应该使用更安全的加密方法
            char[] chars = data.ToCharArray();

            for (int i = 0; i < chars.Length; i++)
            {
                chars[i] = (char)(chars[i] ^ encryptionKey[i % encryptionKey.Length]);
            }

            return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(chars));
        }

        /// <summary>
        /// 解密数据
        /// </summary>
        /// <param name="encryptedData">加密的数据</param>
        /// <returns>解密后的数据</returns>
        private string DecryptData(string encryptedData)
        {
            try
            {
                byte[] bytes = Convert.FromBase64String(encryptedData);
                char[] chars = System.Text.Encoding.UTF8.GetString(bytes).ToCharArray();

                for (int i = 0; i < chars.Length; i++)
                {
                    chars[i] = (char)(chars[i] ^ encryptionKey[i % encryptionKey.Length]);
                }

                return new string(chars);
            }
            catch (Exception e)
            {
                Debug.LogError($"解密失败: {e.Message}");
                return string.Empty;
            }
        }

        #endregion

        #region ScriptableObject Lifecycle

        /// <summary>
        /// 当ScriptableObject被启用时调用
        /// </summary>
        private void OnEnable()
        {
            lastSaveTime = Time.time;
        }

        /// <summary>
        /// 当ScriptableObject被禁用时调用
        /// </summary>
        private void OnDisable()
        {
            if (isDirty && currentUserData != null)
            {
                SaveUserData();
            }
        }

        #endregion
    }
}
